/*
 * NetworkEventData.cpp
 *
 *  Created on: Sep 13, 2011
 *      Author: erudhes
 */
#include <wx/socket.h>
#include "NetworkEventData.h"
#include "SmartPointer.h"
#include "WxUtils.h"

NetworkEventData::NetworkEventData(): mDataType((DataType)htonl((int)INVALID)),
                                      mX(htonl(-1)), mY(htonl(-1)),
                                      mDataLength(htonl(0)),
                                      mData(NULL)
{
	// Nothing to do
}

NetworkEventData::NetworkEventData(char* buffer)
{
	// Everything is stored in network byte order
	mDataType = *((DataType*)(buffer));
	buffer += sizeof(DataType);
	mX = *((int*)(buffer));
	buffer += sizeof(int);
	mY = *((int*)(buffer));
	buffer += sizeof(int);
	mDataLength = *((int*)(buffer));
	// It is the caller's responsibility to set the dynamic data if needed
	mData = NULL;
}

NetworkEventData::~NetworkEventData()
{
	if(NULL != mData)
		delete[] mData;
	mData = NULL;
}

bool NetworkEventData::read(wxSocketBase* socket)
{
	const unsigned int size = sizeof(NetworkEventData);
	ArraySmartPointer<char> buffer = NULL;

	socket->Read(this, size);
	// mData is filled with some invalid data from the remote side, so set it to NULL
	mData = NULL;
	// Check if an error occurred or not
	if(WxUtils::NONE != WxUtils::getSocketError(socket, size))
		return false;
	// If there is no more data to read just return
	if(0 == this->getDataLength())
		return true;
	buffer = new char[this->getDataLength() + 1];
	memset(buffer, 0, this->getDataLength() + 1);
	socket->Read(buffer, this->getDataLength());
	// Check if an error occurred or not
	if(WxUtils::NONE != WxUtils::getSocketError(socket, this->getDataLength()))
		return false;
	this->setRawData(buffer, this->getDataLength());

	return true;
}

bool NetworkEventData::write(wxSocketBase* socket)
{
	const unsigned int size = sizeof(NetworkEventData);

	socket->Write(this, size);
	// Check if an error occurred or not
	if(WxUtils::NONE != WxUtils::getSocketError(socket, size))
		return false;
	// If there is no more data to send just return
	if(0 == this->getDataLength())
		return true;
	socket->Write(this->getRawData(), this->getDataLength());
	if(WxUtils::NONE != WxUtils::getSocketError(socket, this->getDataLength()))
		return false;

	return true;
}

void NetworkEventData::rejectConnection(wxSocketServer* serverSocket)
{
	wxSocketBase* socket =  NULL;

	socket = serverSocket->Accept();
	this->setDataType(NetworkEventData::CONNECTING_REJECT);
	this->write(socket);
	socket->Destroy();
}
